﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;


namespace RegexTools
{
    class Program
    {
        static void Main(string[] args)
        {
            var tests = new[] {
                // anchors
                @"^abc$",
                @"\Aa",
                @"z\Z",
                @"z\z",
                @"z\z",
                @"\G\(a\)",
                @"ab\b",
                @"a\Bb",

                // character escapes
                @"\a",
                @"[\b]",
                @"\t",
                @"\r",
                @"\v",
                @"\f",
                @"\n",
                @"\e",
                @"\141",
                @"\x61",
                @"\cC",
                @"\u0061",
                @"\\",

                // character classes
                @"[abc]",
                @"[^abc]",
                @"[a-z]",
                @".",
                //@"\p{Lu}", // not supported
                //@"\P{Lu}",
                @"\w",
                @"\W",
                @"\s",
                @"\S",
                @"\d",
                @"\D",

                // backreference constructs
                @"(a)\1",
                @"(?<n>a)\k<n>",
                @"(?<n>a)\1",
                @"(a)(?<n>b)\1\2",
                @"(?<n>a)(b)\1\2",
                //@"(?<n>a)(b)\2(c)", // unmatchable, see http://stackoverflow.com/questions/4310082
                @"(a(b))\1\2",
                @"(a(b)(c(d)))\1\2\3\4",
                @"a\0",

                // quantifiers
                @"ab*",
                @"ab+",
                @"ab?",
                @"ab{2}",
                @"ab{2,}",
                @"ab{2,3}",
                @"ab*?",
                @"ab+?",
                @"ab??",
                @"ab{2}?",
                @"ab{2,}?",
                @"ab{2,3}?",

                // disjuncts
                @"a|(b|c)",

                // other
                @"/users(?:/(?<id>\d+))?",
            };
            int passes = 0;
            var revex = new Revex();

            foreach(var pat in tests)
            {
                string rev = revex.Reverse(pat);
                bool pass = Regex.IsMatch(rev, "^(?:" + pat + ")$");
                if (pass) passes++;
                Console.WriteLine("{0,-25} > {1,-20} : {2}", pat, Regex.Escape(rev), pass ? "pass" : "FAIL");
            }

            Console.WriteLine("Passed {0}/{1} tests.", passes, tests.Length);
            Console.ReadLine();
        }
    }
}
